###############################################################################
# vector3
#
class vector3:
	"""
	vector3()
	vector3([x, y, z])
	"""

	def __init__(self, vector = None):
		self.data = [0.0, 0.0, 0.0]
		if vector != None:
			self.data[0] = vector[0]
			self.data[1] = vector[1]
			self.data[2] = vector[2]

	def __getitem__(self, index):
		if index == 0:
			returnValue = self.data[0]
		elif index == 1:
			returnValue = self.data[1]
		elif index == 2:
			returnValue = self.data[2]
		return returnValue

	def __call__(self, vector = None):
		if vector != None:
			self.data[0] = vector[0]
			self.data[1] = vector[1]
			self.data[2] = vector[2]
		else:
			return vector3([self.data[0], self.data[1], self.data[2]])
	
	def __str__(self):
		return str([self.data[0], self.data[1], self.data[2]])

	def __add__(self, other):
		if type(other) == type(self):
			returnValue = vector3([self.data[0] + other.data[0], self.data[1] + other.data[1], self.data[2] + other.data[2]])
		elif type(other) == type(0.0) or type(other) == type(0):
			returnValue = vector3([self.data[0] + other, self.data[1] + other, self.data[2] + other])
		else:
			returnValue = None
		return returnValue

	def __iadd__(self, other):
		if type(other) == type(self):
			self.data[0] += other.data[0]
			self.data[1] += other.data[1]
			self.data[2] += other.data[2]
			returnValue = vector3([self.data[0], self.data[1], self.data[2]])
		elif type(other) == type(0.0) or type(other) == type(0):
			self.data[0] += other
			self.data[1] += other
			self.data[2] += other
			returnValue = vector3([self.data[0], self.data[1], self.data[2]])
		else:
			pass
		return returnValue

	def __sub__(self, other):
		if type(other) == type(self):
			returnValue = vector3([self.data[0] - other.data[0], self.data[1] - other.data[1], self.data[2] - other.data[2]])
		elif type(other) == type(0.0) or type(other) == type(0):
			returnValue = vector3([self.data[0] - other, self.data[1] - other, self.data[2] - other])
		else:
			returnValue = None
		return returnValue

	def __isub__(self, other):
		if type(other) == type(self):
			self.data[0] -= other.data[0]
			self.data[1] -= other.data[1]
			self.data[2] -= other.data[2]
			returnValue = vector3([self.data[0], self.data[1], self.data[2]])
		elif type(other) == type(0.0) or type(other) == type(0):
			self.data[0] -= other
			self.data[1] -= other
			self.data[2] -= other
			returnValue = vector3([self.data[0], self.data[1], self.data[2]])
		else:
			returnValue = vector3([self.data[0], self.data[1], self.data[2]])
		return returnValue

	def __mul__(self, other):
		if type(other) == type(self):
			returnValue = vector3([self.data[0] * other.data[0], self.data[1] * other.data[1], self.data[2] * other.data[2]])
		elif type(other) == type(0.0) or type(other) == type(0):
			returnValue = vector3([self.data[0] * other, self.data[1] * other, self.data[2] * other])
		else:
			returnValue = None
		return returnValue

	def __imul__(self, other):
		if type(other) == type(self):
			self.data[0] *= other.data[0]
			self.data[1] *= other.data[1]
			self.data[2] *= other.data[2]
			returnValue = vector3([self.data[0], self.data[1], self.data[2]])
		elif type(other) == type(0.0) or type(other) == type(0):
			self.data[0] *= other
			self.data[1] *= other
			self.data[2] *= other
			returnValue = vector3([self.data[0], self.data[1], self.data[2]])
		else:
			returnValue = vector3([self.data[0], self.data[1], self.data[2]])
		return returnValue

	def __div__(self, other):
		if type(other) == type(self):
			returnValue = vector3([self.data[0] / float(other.data[0]), self.data[1] / float(other.data[1]), self.data[2] / float(other.data[2])])
		elif type(other) == type(0.0) or type(other) == type(0):
			returnValue = vector3([self.data[0] / float(other), self.data[1] / float(other), self.data[2] / float(other)])
		else:
			returnValue = None
		return returnValue

	def __idiv__(self, other):
		if type(other) == type(self):
			self.data[0] /= other.data[0]
			self.data[1] /= other.data[1]
			self.data[2] /= other.data[2]
			returnValue = vector3([self.data[0], self.data[1], self.data[2]])
		elif type(other) == type(0.0) or type(other) == type(0):
			self.data[0] /= float(other)
			self.data[1] /= float(other)
			self.data[2] /= float(other)
			returnValue = vector3([self.data[0], self.data[1], self.data[2]])
		else:
			returnValue = vector3([self.data[0], self.data[1], self.data[2]])
		return returnValue

	def __neg__(self):
		return vector3([-self.data[0], -self.data[1], -self.data[2]])

	def tuple(self):
		return self.data[0], self.data[1], self.data[2]

	def list(self):
		return [self.data[0], self.data[1], self.data[2]]

	def magnitude(self):
		return pow((self.data[0] * self.data[0]) + (self.data[1] * self.data[1]) + (self.data[2] * self.data[2]), 0.5)

	def normalize(self, overwrite = None):
		magnitude = self.magnitude()
		if magnitude != 0:
			returnX = self.data[0] / magnitude
			returnY = self.data[1] / magnitude
			returnZ = self.data[2] / magnitude
		else:
			returnX = 0.0
			returnY = 0.0
			returnZ = 0.0
		if overwrite == True:
			self.data[0] = returnX
			self.data[1] = returnY
			self.data[2] = returnZ
		if overwrite != True:
			return vector3([ \
			returnX, \
			returnY, \
			returnZ])

	def cross(self, other = None):
		if other != None:
			return vector3([ \
			self.data[1] * other.data[2] - self.data[2] * other.data[1], \
			self.data[2] * other.data[0] - self.data[0] * other.data[2], \
			self.data[0] * other.data[1] - self.data[1] * other.data[0]])
	
	def dot(self, other = None):
		if other != None:
			return self.data[0] * other.data[0] + self.data[1] * other.data[1] + self.data[2] * other.data[2]
